﻿using System;

namespace Affinity.Flux
{
    /// <summary>
    /// Represents a "contract" value (typically a member of an enumeration) governing the connection of inlets and outlets: inlets with a particular
    /// contract value are paired with outlets bearing the same contract value.
    /// </summary>
    public class Contract
    {
        /// <summary>
        /// Factory method creating a Contract corresponding to the contract value on the specified inlet.
        /// </summary>
        /// <param name="inAttribute"></param>
        /// <returns></returns>
        public static Contract Create(InletAttribute inAttribute)
        {
            return new Contract(inAttribute.Contract);
        }

        /// <summary>
        /// Factory method creating a Contract corresponding to the contract value on the specified outlet.
        /// </summary>
        /// <param name="outAttribute"></param>
        /// <returns></returns>
        public static Contract Create(OutletAttribute outAttribute)
        {
            return new Contract(outAttribute.Contract);
        }

        /// <summary>
        /// Constructor accepting the contract value that this Contract will represent.
        /// </summary>
        /// <param name="value"></param>
        private Contract(object value)
        {
            if (value == null) throw new ArgumentNullException("value");
            _Value = value;
        }

        /// <summary>
        /// Returns whether this object equals the specified object.
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override bool Equals(object obj)
        {
            return object.Equals(obj, _Value);
        }

        /// <summary>
        /// Returns the hash code for this object.
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            return _Value.GetHashCode();
        }

        /// <summary>
        /// Returns a description of this object.
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return string.Format("{0}.{1}", _Value.GetType().Name, _Value);
        }

        private readonly object _Value = null;
    }
}
